#region Namespace

using System;
using System.Data;
using System.Data.SqlClient;

using PHSRAG.Insight21.CDS;
using Utility = PHSRAG.Utility;
using ICachePolicy = PHSRAG.Insight21.Policy.ICachePolicy;

#endregion

namespace PHSRAG.Insight21.COI
{
	/// <summary>
	/// This COIUser object (derived from Person object)will act a container, supporting load/save/update of the user in COI Context.
	/// </summary>
	public class COIUser:Person
	{
		#region private constant cacheKey
		/// <summary>Unique string(key) to cache and uncache coiUser object</summary>
		private const string COIUserKey = "COIUser_60A5C4F8-EAEC-4b2d-81B8-1DCE7579874B";
		/// <summary>stored procedure to sav the object</summary>
		private const string SPSaveCOIUser="SaveCOIPerson";
		/// <summary>stored procedure to load the object</summary>
		private const string SPGetPerson="GetPerson";
		#endregion

		#region private instance variables
		/// <summary>object to hold the COI Role of the user </summary>
		private string coiRole;
		/// <summary>object to hold the outside member flag </summary>
		private bool isOutsideMember=false;
        /// <summary>object to hold the HierarchyType Id flag </summary>
        private int intHierarchyTypeId;
        /// <summary>/// object to hold the ParentId of the current COI Person/// </summary>
        private int intParentId;
        private int intHierarchyTypeIdOld = 0;
		#endregion
		
		#region public properties
		
		/// <summary>Gets/Sets the COI role of the perosn </summary>
		public string COIRole
		{
			get{return coiRole;}
			set{ SetDirty( ref coiRole,value);}
		}

		/// <summary>Gets/Sets outside trustee flag(indicates whether or not the person is a outside board member) </summary>
		public bool IsOutsideMember
		{
			get{return isOutsideMember;}
			set{ SetDirty( ref isOutsideMember, value);}
		}
        
        public int HierarchyTypeId
        {
            get { return intHierarchyTypeId; }
            set
            {
                intHierarchyTypeIdOld = intHierarchyTypeId;
                SetDirty(ref intHierarchyTypeId,value);
            }
        }

        
        private int HierarchyTypeIdOld
        {
            get { return intHierarchyTypeIdOld; }
            set { intHierarchyTypeIdOld = value; }
        }

        public int ParentId
        {
            get { return intParentId; }
            set { SetDirty(ref intParentId,value); }
        }

		#endregion

        #region Enumerations

        public enum HierarchyType
        {
            None = 0,
            Board,
            Committee,
            Institutional
        }

        #endregion Enumerations


        #region constructors
        /// <summary>
		/// The datarow passed in the constructor will be used to set the values for the objects of this container.
		/// </summary>
		/// <param name="cachePolicy">policy used to cache this object</param>
		/// <param name="row">datarow containing the details</param>
			public COIUser(ICachePolicy cachePolicy, DataRow row) : base(cachePolicy)
			{
				PopulateDataMembers(row);
			}

		/// <summary>
		/// NEW object constructor; initializes the base with the specified cache policy
		/// </summary>
		/// <param name="cachePolicy">policy used to cache this object</param>
			public COIUser(ICachePolicy cachePolicy) : base(cachePolicy)
			{
			}
		#endregion

		#region override methods
		/// <summary>
		/// save/update the person to the admPerson.
		/// </summary>
		/// <param name="transaction">transaction to handle database transactions</param>
		protected override void SaveObject(SqlTransaction transaction)
		{
			try
			{
				Id = (int) Utility.DataAccess.ExecuteScalar(
					transaction.Connection,
					transaction,
					SPSaveCOIUser, 
					Utility.DataAccess.BuildSqlParameterArray(
					"@admPersonId", SqlDbType.Int, Id,
					"@lastName", SqlDbType.VarChar, LastName,
					"@firstName", SqlDbType.VarChar, FirstName,
					"@admPersonType", SqlDbType.Int, AdmPersonType,
					"@orgId", SqlDbType.Int, OrganizationId,
					"@orgName", SqlDbType.VarChar, (OrganizationName == string.Empty || OrganizationName == null) ? (object)DBNull.Value : (object)OrganizationName,
					"@areaCode", SqlDbType.VarChar, (PhoneArea == string.Empty || PhoneArea == null) ? (object)DBNull.Value : (object)PhoneArea,
					"@number", SqlDbType.VarChar, (PhoneNumber == string.Empty || PhoneNumber == null) ? (object)DBNull.Value : (object)PhoneNumber,
					"@email", SqlDbType.VarChar, (Email == string.Empty || Email == null) ? (object)DBNull.Value : (object)Email,
					"@middleName", SqlDbType.VarChar, (MiddleName == string.Empty || MiddleName ==null) ? (object)DBNull.Value : (object)MiddleName,
					"@admDegreeId", SqlDbType.Int, (DegreeId == 0) ? (object)DBNull.Value : (object)DegreeId,
					"@dept", SqlDbType.VarChar, (Department == string.Empty || Department == null) ? (object)DBNull.Value : (object)Department,
					"@title", SqlDbType.VarChar, (Title == string.Empty || Title == null) ? (object)DBNull.Value : (object)Title,
					"@faxAreaCode", SqlDbType.VarChar, (FaxArea == string.Empty || FaxArea == null) ? (object)DBNull.Value : (object)FaxArea,
					"@faxNumber", SqlDbType.VarChar, (FaxNumber == string.Empty || FaxNumber == null) ? (object)DBNull.Value : (object)FaxNumber,
				    "@cOIRole", SqlDbType.VarChar,(coiRole == string.Empty || coiRole == null) ? (object)DBNull.Value : (object)coiRole,
					"@isOutsideMember", SqlDbType.Bit,isOutsideMember,
                    "@HierarchyTypeId",SqlDbType.Int,HierarchyTypeId,
                    "@HierarchyTypeIdOld", SqlDbType.Int, HierarchyTypeIdOld,
                    "@ParentId", SqlDbType.Int, ParentId
					));

				Address.AdmPersonId = Id;
				Address.Save(transaction);

				dirty = false;
			}
			catch(Exception e)
			{
				Utility.ExceptionReport.WriteToEventLog(
					"Failed to save the COI User details.", e, true, Utility.ExceptionReport.ReportType.Error);
				throw new Exception("Failed to save the COI User details.", e);
			}
		}

		/// <summary>
		/// Loads the object using admPersonId
		/// </summary>
		/// <param name="connectionString">contains info to connect to the data source</param>
		/// <param name="args">arguments for the stored procedure</param>
		public override void Load(string connectionString, params object[] args)
		{
			if (args.Length < 1)
				throw new Exception("Person load requires an AdmPersonId");

			try
			{
				PopulateDataMembers(Utility.DataAccess.GetDataSet(
					connectionString,
					SPGetPerson,
					Utility.DataAccess.BuildSqlParameterArray("@admPersonId", SqlDbType.Int, args[0],
                                                              "@ParentId",SqlDbType.Int, args[1],
                                                              "@HierarchyTypeId", SqlDbType.Int, args[2]
                                                                )).Tables[0].Rows[0]);

				Id = (int)args[0];

				// object will have been marked dirty if any of the loaded values are different,
				// and it should be flipped back to False
				// than the defaults
				Dirty = false;
			}
			catch(Exception e)
			{
				Utility.ExceptionReport.WriteToEventLog(
					"Failed to load the COI User details", e, true, Utility.ExceptionReport.ReportType.Error);
				throw new Exception("Failed to load the COI User details", e);
			}
		}
		#endregion

		#region private methods
		/// <summary>
		/// Private method used to populate member variables from a DataRow. This is called from the 
		/// constructor that takes a DataRow, as well as the Load method of an object.
		/// </summary>
		/// <param name="row">row whose data is used to populate instance variables</param>
		private void PopulateDataMembers(DataRow row)
		{
			try
			{
				LastName = (string) row["LastName"];
				FirstName = (string) row["FirstName"];
				object o = row["Username"];
				Username = (o == DBNull.Value) ? string.Empty : (string)o;
				o = row["OrganizationId"];
				OrganizationId = (o == DBNull.Value) ? 0 : (int)o;
				o = row["OrganizationName"];
				OrganizationName = (o == DBNull.Value) ? string.Empty : (string)o;
				AdmPersonType = (int)row["AdmPersonTypeId"];
				o = row["RecomAbstractId"];
				RexRecomId = (o == DBNull.Value) ? 0 : (int)o;
				o = row["COIRole"];
				coiRole = (o == DBNull.Value) ? string.Empty : (string)o;
				o = row["OutsideMember"];
				isOutsideMember = (o == DBNull.Value) ? false : (bool)o;
                o = row["HierarchyTypeId"];
                intHierarchyTypeId = (o == DBNull.Value) ? 0 : (int)o;
                o = row["ParentId"];
                intParentId = (o == DBNull.Value) ? 0 : (int)o;
			}
			catch(Exception ex)
			{
				Utility.ExceptionReport.WriteToEventLog(
					"Failed to populate the COIUser member variable", ex, true, Utility.ExceptionReport.ReportType.Error);
				throw new Exception("Failed to populate the COIUser member variable", ex);
			}
		}
		#endregion

		#region caching
		/// <summary>
		/// Cache this instance using the prevalent cache policy.
		/// </summary>
		public override void Cache()
		{
			CachePolicy.Cache(COIUserKey, this);
		}

		/// <summary>
		/// Remove this instance from the cache using the prevalent cache policy.
		/// </summary>
		public override void UnCache()
		{
			CachePolicy.UnCache(COIUserKey);
		}
		#endregion
	}
}
